package com.jing.cloud.service.impl;

import com.alibaba.fastjson.JSON;
import com.jing.cloud.service.MicroService;
import com.jing.cloud.service.Req;
import com.jing.cloud.service.Rsp;
import com.jing.cloud.service.config.ServConf;
import com.jing.cloud.service.method.Method;
import com.jing.cloud.service.methodfactory.MethodFactory;
import com.jing.cloud.util.ErrCode;
import com.jing.cloud.util.RspUtil;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class MicroServiceImpl implements MicroService.Iface {

    private static final Logger logger = LoggerFactory.getLogger(MicroServiceImpl.class);

    @Override
    public Rsp callMethod(Req req) throws TException {
        return call(req);
    }

    @Override
    public void callMethodOneway(Req req) throws TException {
        call(req);
    }

    private Rsp call(Req req) {
        long start = System.currentTimeMillis();
        if (ServConf.isReqLogOn()) {
            logger.info("call method[{}] start req:[{}]", req.getMethodName(), req);
        }
        Rsp rsp = null;
        try {
            @SuppressWarnings("unchecked")
            Method<Object> method = MethodFactory.getMethod(req.getMethodName());
            if (method == null) {
                // 方法没有找到，方法没有注册
                rsp = RspUtil.error(ErrCode.METHOD_NOT_FOUND).toRsp();
            } else {
                method.setUserId(req.getUserId());
                Class<Object> clazz = method.getClazz();
                // json解析是否有成功
                boolean jsonParsed = false;
                // 暂定参数为json格式字符串
                Object input = null;
                try {
                    input = JSON.parseObject(req.param, clazz);
                    jsonParsed = true;// json 解析成功
                } catch (Exception e) {
                    // json 解析失败
                    rsp = RspUtil.error(ErrCode.JSON_PARSE_ERROR, e).toRsp();
                    logger.error("call method json prase error req:[{}]", req, e);
                }
                if (jsonParsed) {

                    // 参数校验
                    rsp = method.validAndRun(input).toRsp();
                }
            }
        } catch (Exception e) {
            // 其他未处理的异常
            rsp = RspUtil.error(ErrCode.SERVER_ERROR, e).toRsp();
            logger.error("call method error req:[{}]", req, e);
        }
        long end = System.currentTimeMillis();
        if (ServConf.isReqLogOn()) {
            logger.info("call method[{}] end rsp:[{}]", req.getMethodName(), rsp);
            logger.info("call method[{}] end use[{}ms]", req.getMethodName(), end - start);
        }

        return rsp;
    }

}
